package service;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;

import dao.AccountDao;
import exception.BadDataException;

import socket.handler.ServerSocketHandler;
import socket.handler.SocketHandler;
import socket.receiver.ServerReceiver;
import util.BinarySearchTree;

import com.tntgroup.sudokuonline.message.CreateRoomMessage;
import com.tntgroup.sudokuonline.message.DeleteRoomMessage;
import com.tntgroup.sudokuonline.message.LoginMessage;
import com.tntgroup.sudokuonline.message.LogoutMessage;
import com.tntgroup.sudokuonline.message.Message;
import com.tntgroup.sudokuonline.message.RegisterMessage;
import model.Account;
import model.Player;
import model.Room;

public class ServerMediator {
//	private ArrayList<SocketHandler> handlers=new ArrayList<SocketHandler>();
	@Autowired
	private BinarySearchTree tree;
	@Autowired
	private Lobby lobby;
	@Autowired
	private AccountDao accountDao;
	
	public AccountDao getAccountDao() {
		return accountDao;
	}
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	public synchronized void registerClient(Socket socket,ObjectInputStream in,ObjectOutputStream out){
		ServerSocketHandler socketHandler=new ServerSocketHandler(socket, in, out, this);
		ServerReceiver receiver=new ServerReceiver(socketHandler);
		receiver.start();
		
	}
	public void sendMessage(Message message,SocketHandler handler){
//		SocketHandler handler=Arrays.binarySearch(handlers.toArray(), hd, new SocketHandlerComparator());
		try {
			handler.writeSocket(message);
		} catch (BadDataException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void broadcastMessage(Message message,ArrayList<SocketHandler> handlers){
//		for(SocketHandler handler:handlers){
//			handler.writeSocket(message);
//		}
		
	}
	public void analyzeMessage(Message message,SocketHandler handler){
		if(message.getType().equals(Message.MESSAGE_CREATE_ROOM)){
			CreateRoomMessage createRoom=(CreateRoomMessage) message;
			Room room=new Room();
			room.setLevel(createRoom.getLevel());
			room.setRoomId(createRoom.getRoomid());
			lobby.createRoom(room);
		}
		else if(message.getType().equals(Message.MESSAGE_DELETE_ROOM)){
			DeleteRoomMessage deleteRoom=(DeleteRoomMessage) message;
			lobby.deleteRoom(deleteRoom.getRoomid());
		}
		else if(message.getType().equals(Message.MESSAGE_JOIN_ROOM)){
			
		}
		else if(message.getType().equals(Message.MESSAGE_LEAVE_ROOM)){
			
		}
		else if(message.getType().equals(Message.MESSAGE_LOGIN)){
			LoginMessage login=(LoginMessage) message;
			String username=login.getUsername();
			String password=login.getPassword();
			long id=accountDao.checkAccount(username, password);
			if(id==-1){				
				message.setStatus(Message.FAIL);
				System.out.println("login fail");
			}
			else{							
				if(!lobby.checkExistPlayer(id)){
					Player player=new Player();
					player.setId(id);
					player.setStatus("online");					
					lobby.getPlayers().add(player);
					ServerSocketHandler shandler=(ServerSocketHandler) handler;
					shandler.setId(id);	
					tree.add((ServerSocketHandler)handler);
					message.setStatus(Message.OK);
					System.out.println("login successfully");					
				}
				else{
					message.setStatus(Message.FAIL);
					System.out.println("login ready");	
				}
			}
			sendMessage(message, handler);
		}
		else if(message.getType().equals(Message.MESSAGE_LOGOUT)){
			LogoutMessage logout=(LogoutMessage) message;
			String username=logout.getUsername();
			String password=logout.getPassword();
			long id=accountDao.checkAccount(username, password);		
			if(id==-1){
				message.setStatus(Message.FAIL);
				System.out.println("logout fail");
			}
			else{
				ServerSocketHandler shandler=(ServerSocketHandler) handler;
				if(tree.remove(shandler)){
					Player p=lobby.find(id);
					if(p!=null){
						lobby.getPlayers().remove(p);
					}
					message.setStatus(Message.OK);			
					System.out.println("logout success");
					
				}
				else{
					message.setStatus(Message.FAIL);
					System.out.println("remove fail");
				}
				
			}
			sendMessage(message, handler);	
		}
		else if(message.getType().equals(Message.MESSAGE_PLAY)){
			
		}
		else if(message.getType().equals(Message.MESSAGE_REGISTER)){
			RegisterMessage register=(RegisterMessage) message;
			Account account=new Account();
			account.setUsername(register.getUsername());
			account.setPassword(register.getPassword());
			account.setEmail(register.getEmail());
			account.setWin(0);
			account.setLose(0);
			System.out.println("creating account");
			if(accountDao.createAccount(account)){				
				System.out.println("create account successfully");
			}
			else{
				System.out.println("create account unsuccessfully");
			}

		}
		
	}
}
